package com.diamond.web.controller.system;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.diamond.web.utils.ApplicationInitUtils;
import com.diamond.web.utils.SK;
import com.diamond.core.entity.Result;
import com.diamond.core.util.ApplicationUtils;
import com.diamond.web.controller.GenericController;
import com.diamond.web.dto.RoleDto;
import com.diamond.web.exceptions.AppException;
import com.diamond.web.model.system.Role;
import com.diamond.web.model.system.User;
import com.diamond.web.service.system.RoleService;
import com.diamond.web.service.system.UserService;

/**
 * 用户控制器
 * 
 * @author StarZou
 * @since 2014年5月28日 下午3:54:00
 **/
@Controller
@RequestMapping(value = "admin/user") //admin/user/login
public class UserController extends GenericController{

    @Resource
    private UserService userService;
    
    @Resource
    private RoleService roleService;
    /**
     * 用户登录
     * 
     * @param user
     * @param result
     * @return
     */
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public String login(@Valid User user, BindingResult result, Model model, HttpServletRequest request) {
        try {
        	if (result.hasErrors()) {
        		model.addAttribute("error", "参数错误！");
        		return "redirect:login";
        	}
        	Subject subject = SecurityUtils.getSubject();
            // 身份验证
            user.setPassword(ApplicationUtils.pwd(user.getPassword()));
            subject.login(new UsernamePasswordToken(user.getUsername(), user.getPassword()));
            // 验证成功在Session中保存用户信息
            final User authUserInfo = userService.selectByUsername(user.getUsername());      
            getSession().setAttribute(SK.USER_INFO, authUserInfo);
            if(ApplicationInitUtils.SuperAdmin.equals(user.getUsername())){
            	getSession().setAttribute(SK.USER_INFO, user);
            }
        } catch (AuthenticationException e) {
            // 身份验证失败
            model.addAttribute("error", "用户名或密码错误 ！");
            return "redirect:login";
        }
        return "redirect:../index";
    }

    /**
     * 登录页
     */
    @RequestMapping("/login")
    public ModelAndView login(String redirect) {    	
    	ModelAndView mv = new ModelAndView();
    	mv.addObject("redirect", redirect);
    	mv.setViewName("admin/login");
        return mv;
    }
    
    @RequestMapping("/login_expires")
    public String login_expires(){
    	return "admin/login_expires";
    }
    
    /**
     * 用户登出
     * 
     * @param session
     * @return
     */
    @RequestMapping(value = "/logout", method = RequestMethod.GET)
    public String logout(HttpSession session) {
        session.removeAttribute("userInfo");
        // 登出操作
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return "redirect:admin/login";
    }

	@RequestMapping("list")
	public ModelAndView toList(){
		ModelAndView mv  = getModelAndView("list");
		return mv;
	}
	
	@RequestMapping("listData")
	@ResponseBody
	public List<User> list() {
		return userService.selectList();
	}
	
	@RequestMapping("add")
	public ModelAndView toAdd(){
		ModelAndView mv = getModelAndView("save");
		List<Role> allRoles = roleService.selectList();
		List<RoleDto> dtos = new ArrayList<RoleDto>();
		for (Role role : allRoles) {
			RoleDto dto = new RoleDto(role);
			dtos.add(dto);
		}
		mv.addObject("roles",dtos);
		return mv;
	}
	
	@RequestMapping("edit")
	public ModelAndView toEdit(Long id){
		ModelAndView mv = getModelAndView("save");
		mv.addObject("m", userService.selectById(id));
		List<Role> allRoles = roleService.selectList();
		List<Role> hasRoles = roleService.selectRolesByUserId(id);
		List<RoleDto> dtos = new ArrayList<RoleDto>();
		for (Role role : allRoles) {
			RoleDto dto = new RoleDto(role);
			for(Iterator<Role> it = hasRoles.iterator();it.hasNext();){
				Role r = it.next();
				if(r.getId().equals(role.getId())){
					dto.setHasRole(true);
					it.remove();
					break;
				}
			}
			dtos.add(dto);
		}
		mv.addObject("roles", dtos);
		return mv;
	}

	
	@RequestMapping("addData")
	@ResponseBody
	public Result addData(@Valid User model,BindingResult validResult,Long[] roleIds) throws ReflectiveOperationException, AppException{
		if(ApplicationInitUtils.SuperAdmin.equals(model.getUsername())){
			throw new AppException(AppException.USER_EXIST);
		}
		Result result = new Result();
		if(roleIds!=null&&roleIds.length>0){
			List<Role> roles = ApplicationUtils.FieldsToObject(Arrays.asList(roleIds), "setId", Role.class);
			model.setRoles(new HashSet<Role>(roles));
		}
		userService.register(model);
		result.setSuccess(true);
		return result;
	}
	
	@RequestMapping("editData")
	@ResponseBody
	public Result editData(User model,Long[] roleIds) throws ReflectiveOperationException{
		userService.modify(model,roleIds);
		return new Result();
	}
	
}
